package com.greens1995.testmap;

import android.Manifest;
import android.content.pm.PackageManager;
import android.location.Location;
import android.os.Bundle;
import android.support.v4.app.ActivityCompat;
import android.support.v4.app.FragmentActivity;
import android.support.v4.view.ViewPager;
import android.view.MotionEvent;
import android.view.View;
import android.widget.RelativeLayout;
import android.widget.Toast;

import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.UiSettings;
import com.google.android.gms.maps.model.CameraPosition;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.LatLngBounds;
import com.google.maps.android.clustering.Cluster;
import com.google.maps.android.clustering.ClusterItem;
import com.google.maps.android.clustering.ClusterManager;
import com.greens1995.testmap.locate.LocationHelper;
import com.greens1995.testmap.model.Person;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

import static com.greens1995.testmap.R.id.map;

public class MapsActivity extends FragmentActivity implements OnMapReadyCallback, ClusterManager.OnClusterClickListener<Person>, ClusterManager.OnClusterInfoWindowClickListener<Person>, ClusterManager.OnClusterItemClickListener<Person>, ClusterManager.OnClusterItemInfoWindowClickListener<Person>, ViewPager.OnPageChangeListener {

    private GoogleMap mMap;
    private LocationHelper locationHelper;
    private ClusterManager<Person> mClusterManager;
    private PersonRenderer personRenderer;
    private Random mRandom = new Random(1984);

    private RelativeLayout vpContainer;
    private CustomViewPager viewPager;
    private ViewpagerAdapter mAdapter;

    private List<Person> persons;
    private int mPosition;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_maps);
        initView();
        initLocate();
    }


    private void initLocate() {

        locationHelper = LocationHelper.newInstance(this);
        locationHelper.setAsyncLocateListener(new LocationHelper.AsyncLocateListener() {
            @Override
            public void onLocate(Location location) {
                Toast.makeText(MapsActivity.this, "纬度：" + location.getLatitude() + "-经度：" + location.getLongitude() + location.describeContents(), Toast.LENGTH_LONG).show();
                mMap.animateCamera(CameraUpdateFactory.newCameraPosition(new CameraPosition.Builder().target(new LatLng(location.getLatitude(), location.getLongitude()))
                        .zoom(8f)
                        .bearing(0)
                        .tilt(25)
                        .build()));
                mAdapter.setMainLocation(location);
            }

            @Override
            public void onLocateFail() {
                Toast.makeText(MapsActivity.this, "定位失败", Toast.LENGTH_LONG).show();

            }

            @Override
            public void onConnectSuspended(int i) {

            }

            @Override
            public void onConnectfail(ConnectionResult connectionResult) {

            }
        });
    }

    private void initView() {
        vpContainer = (RelativeLayout) findViewById(R.id.ry_container);
        viewPager = (CustomViewPager) findViewById(R.id.vp);
        vpContainer.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                return viewPager.dispatchTouchEvent(event);
            }
        });

        SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
                .findFragmentById(map);
        mapFragment.getMapAsync(this);

        persons = new ArrayList<Person>();
        mAdapter = new ViewpagerAdapter(this, persons);
        viewPager.setAdapter(mAdapter);
        //设置缓存数为展示的数目
        viewPager.setOffscreenPageLimit(persons.size());
        viewPager.setPageMargin(10);
        //设置切换动画
        viewPager.setPageTransformer(true, new ZoomOutPageTransformer());
        viewPager.addOnPageChangeListener(this);
//        setViewPagerSpeed(250);
    }


    /**
     * Manipulates the map once available.
     * This callback is triggered when the map is ready to be used.
     * This is where we can add markers or lines, add listeners or move the camera. In this case,
     * we just add a marker near Sydney, Australia.
     * If Google Play services is not installed on the device, the user will be prompted to install
     * it inside the SupportMapFragment. This method will only be triggered once the user has
     * installed Google Play services and returned to the app.
     */
    @Override
    public void onMapReady(GoogleMap googleMap) {
        mMap = googleMap;
        configMap(mMap);
        initCluster(mMap);
        mockPerson();
        clust(persons);
        mAdapter.notifyDataSetChanged();
    }

    private void clust(List<Person> persons) {
        mClusterManager.addItems(persons);
        mClusterManager.cluster();
    }

    private void initCluster(GoogleMap mMap) {
        mClusterManager = new ClusterManager<Person>(this, mMap);
        personRenderer = new PersonRenderer(this, mMap, mClusterManager);
        mClusterManager.setRenderer(personRenderer);

        mMap.setOnCameraIdleListener(mClusterManager);
        mMap.setOnMarkerClickListener(mClusterManager);
//        mMap.setOnInfoWindowClickListener(mClusterManager);
        mClusterManager.setOnClusterClickListener(this);
//        mClusterManager.setOnClusterInfoWindowClickListener(this);
        mClusterManager.setOnClusterItemClickListener(this);
//        mClusterManager.setOnClusterItemInfoWindowClickListener(this);
    }

    private void configMap(GoogleMap mMap) {
        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            // TODO: Consider calling
            //    ActivityCompat#requestPermissions
            // here to request the missing permissions, and then overriding
            //   public void onRequestPermissionsResult(int requestCode, String[] permissions,
            //                                          int[] grantResults)
            // to handle the case where the user grants the permission. See the documentation
            // for ActivityCompat#requestPermissions for more details.
            return;
        }
        mMap.setPadding(100, 100, 100, 100);
        mMap.setMyLocationEnabled(true);
        UiSettings uiSettings = mMap.getUiSettings();
        uiSettings.setMyLocationButtonEnabled(true);
    }

    @Override
    public boolean onClusterClick(Cluster<Person> cluster) {
        // Show a toast with some info when the cluster is clicked.
        String firstName = cluster.getItems().iterator().next().name;
        Toast.makeText(this, cluster.getSize() + " (including " + firstName + ")", Toast.LENGTH_SHORT).show();

        // Zoom in the cluster. Need to create LatLngBounds and including all the cluster items
        // inside of bounds, then animate to center of the bounds.

        // Create the builder to collect all essential cluster items for the bounds.
        LatLngBounds.Builder builder = LatLngBounds.builder();
        for (ClusterItem item : cluster.getItems()) {
            builder.include(item.getPosition());
        }
        // Get the LatLngBounds
        final LatLngBounds bounds = builder.build();

        // Animate camera to the bounds
        try {
            mMap.animateCamera(CameraUpdateFactory.newLatLngBounds(bounds, 100));
        } catch (Exception e) {
            e.printStackTrace();
        }

        return true;
    }

    @Override
    public void onClusterInfoWindowClick(Cluster<Person> cluster) {
        // Does nothing, but you could go to a list of the users.
    }

    @Override
    public boolean onClusterItemClick(Person item) {
        // Does nothing, but you could go into the user's profile page, for example.
        viewPager.setCurrentItem(persons.indexOf(item));
        return false;
    }

    @Override
    public void onClusterItemInfoWindowClick(Person item) {
        // Does nothing, but you could go into the user's profile page, for example.
    }


    private void mockPerson() {
        persons.add(new Person(position(), "Walter", R.drawable.walter));
        persons.add(new Person(position(), "Gran", R.drawable.gran));
        persons.add(new Person(position(), "Ruth", R.drawable.ruth));
        persons.add(new Person(position(), "Stefan", R.drawable.stefan));
        persons.add(new Person(position(), "Mechanic", R.drawable.mechanic));
        persons.add(new Person(position(), "Yeats", R.drawable.yeats));
        persons.add(new Person(position(), "John", R.drawable.john));
        persons.add(new Person(position(), "Trevor the Turtle", R.drawable.turtle));
        persons.add(new Person(position(), "Teach", R.drawable.teacher));
        persons.add(new Person(position(), "Walter", R.drawable.walter));
        persons.add(new Person(position(), "Yeats", R.drawable.yeats));
        persons.add(new Person(position(), "Walter", R.drawable.walter));
        persons.add(new Person(position(), "Walter", R.drawable.walter));
        persons.add(new Person(position(), "Walter", R.drawable.walter));
        persons.add(new Person(position(), "Stefan", R.drawable.stefan));
        persons.add(new Person(position(), "Walter", R.drawable.walter));
        persons.add(new Person(position(), "Ruth", R.drawable.ruth));
        persons.add(new Person(position(), "Walter", R.drawable.walter));
        persons.add(new Person(position(), "Gran", R.drawable.gran));
    }

    @Override
    protected void onStart() {
        locationHelper.start();
        super.onStart();
    }

    @Override
    protected void onStop() {
        locationHelper.stop();
        super.onStop();
    }

    @Override
    protected void onPause() {
        super.onPause();
    }

    @Override
    public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
        mPosition = position;
    }

    @Override
    public void onPageSelected(int position) {
        LatLng latLng = persons.get(position).getPosition();
        mMap.animateCamera(CameraUpdateFactory.newCameraPosition(new CameraPosition.Builder().target(new LatLng(latLng.latitude, latLng.longitude))
                .zoom(8f)
                .bearing(0)
                .tilt(25)
                .build()));
        if (personRenderer.getMarker(persons.get(position)) != null && personRenderer.getMarker(persons.get(position)).isVisible()) {
            personRenderer.getMarker(persons.get(position)).showInfoWindow();
        }
        //当手指左滑速度大于2000时viewpager右滑（注意是item+2）
        if (viewPager.getSpeed() < -1800) {

            viewPager.setCurrentItem(mPosition + 2);
            viewPager.setSpeed(0);
        } else if (viewPager.getSpeed() > 1800 && mPosition > 0) {
            //当手指右滑速度大于2000时viewpager左滑（注意item-1即可）
            viewPager.setCurrentItem(mPosition - 1);
            viewPager.setSpeed(0);
        }
    }

    @Override
    public void onPageScrollStateChanged(int state) {

    }

    private LatLng position() {
        return new LatLng(random(22.1013432, 23.28494009999999), random(112.368271, 114.3714683));
    }

    private double random(double min, double max) {
        return mRandom.nextDouble() * (max - min) + min;
    }

}
